package com.zonhar.autofeed.common.device.i2c;

import com.pi4j.gpio.extension.pca.PCA9685GpioProvider;
import com.pi4j.gpio.extension.pca.PCA9685Pin;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinPwmOutput;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.i2c.I2CBus;
import com.pi4j.io.i2c.I2CFactory;

import java.io.IOException;
import java.math.BigDecimal;

/**
 * 驱动pca9685
 */
public class Pca9685DeviceUtils {

    public static void run() {
        try {
            BigDecimal frequency = new BigDecimal("50");
            //设定舵机控制频率，一般来说是50hz，一个周期20ms
            BigDecimal frequencyCorrectionFactor = new BigDecimal("1");
            //设定修正因子，PCA9685的实际输出频率与设定的频率有误差 所以说需要修正，如果必须要纠正只需要填写1就好
            I2CBus bus = I2CFactory.getInstance(I2CBus.BUS_1);
            final PCA9685GpioProvider provider = new PCA9685GpioProvider(bus, 0x40, frequency, frequencyCorrectionFactor);
            provisionPwmOutputs(provider);
            provider.reset();
            Pin pin_0 = PCA9685Pin.ALL[0];
            provider.setPwm(pin_0,0, 500);
            //这里的第三个值与舵机控制角度有关
            //计算公式:date=4096*((angle*11)+500)/20000
            Thread.sleep(230);
            //这里要添加休眠 否则舵机可能来不及反应
            provider.setPwm(pin_0,0, 300);
//            provider.setPwm(pin_0,0, 500);
//            Thread.sleep(1000);
//            provider.setPwm(pin_0,0, 300);
        }catch (RuntimeException | InterruptedException e){
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (I2CFactory.UnsupportedBusNumberException e) {
            e.printStackTrace();
        }

    }

    private static GpioPinPwmOutput[] provisionPwmOutputs(final PCA9685GpioProvider gpioProvider) {
        GpioController gpio = GpioFactory.getInstance();
        GpioPinPwmOutput myOutputs[] = {
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_00, "uesd"),
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_01, "not used"),
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_02, "not used"),
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_03, "not used"),
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_04, "not used"),
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_05, "not used"),
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_06, "not used"),
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_07, "not used"),
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_08, "not used"),
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_09, "not used"),
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_10, "not used"),
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_11, "not used"),
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_12, "not used"),
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_13, "not used"),
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_14, "not used"),
                gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_15, "not used")};
        //注意这里要把所有的都给初始化
        return myOutputs;
    }
}
